package com.example.blog.controller;

import com.baomidou.mybatisplus.core.conditions.query.LambdaQueryWrapper;
import com.baomidou.mybatisplus.core.metadata.IPage;
import com.baomidou.mybatisplus.extension.plugins.pagination.Page;
import com.example.blog.config.PublisherAware;
import com.example.blog.domain.Announcement;
import com.example.blog.domain.OperationalLogs;
import com.example.blog.domain.Response;
import com.example.blog.dto.announcement.AdminSelectAnnouncementDto;
import com.example.blog.dto.operationalLogs.OperationLogsDto;
import com.example.blog.event.publisher.LoggingApplicationEvent;
import com.example.blog.exception.BusinessException;
import com.example.blog.exception.SystemException;
import com.example.blog.note.LogInfo;
import com.example.blog.note.NoToken;
import com.example.blog.note.Permissions;
import com.example.blog.service.impl.AnnouncementServiceImpl;
import com.example.blog.dto.announcement.AnnouncementDto;
import com.example.blog.dto.publicDto.QuerySearchDto;
import com.example.blog.utils.IpUtil;
import org.springframework.beans.BeanUtils;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.validation.annotation.Validated;
import org.springframework.web.bind.annotation.*;

import java.util.Objects;
import java.util.Optional;

@RestController
@RequestMapping("/announcement")
public class AnnouncementController extends BaseController {
    private final AnnouncementServiceImpl announcementService;
    private final PublisherAware publisherAware;

    @Autowired
    public AnnouncementController(AnnouncementServiceImpl announcementService, PublisherAware publisherAware) {
        this.announcementService = announcementService;
        this.publisherAware = publisherAware;
    }

    //查询公告内容
    @NoToken
    @LogInfo("查询公告内容")
    @GetMapping("/getAllAnnouncement/{index}")
    public Response getAll(@PathVariable("index") long index) {
        IPage page = new Page(index, 7);
        LambdaQueryWrapper<Announcement> wrapper = new LambdaQueryWrapper<>();
        wrapper.orderByDesc(Announcement::getReleaseTime);
        return new Response(Response.SUCCEED_CODE, "查询公告内容", announcementService.page(page, wrapper).getRecords());
    }

    //Admin查询公告内容
    @Permissions("/announcement/getAll")
    @LogInfo("Admin查询公告内容")
    @PostMapping("/getAll")
    public Response getAllAdmin(@RequestBody AdminSelectAnnouncementDto querySearchDto) {
        IPage page = new Page(querySearchDto.getIndex(), querySearchDto.getPage());
        LambdaQueryWrapper<Announcement> queryWrapper = new LambdaQueryWrapper<>();
        queryWrapper
                .like(Objects.nonNull(querySearchDto.getDateTime()), Announcement::getReleaseTime, querySearchDto.getDateTime())
                .like(Objects.nonNull(querySearchDto.getTitle()), Announcement::getTitle, querySearchDto.getTitle())
                .orderByDesc(Announcement::getReleaseTime);
        Optional.ofNullable(querySearchDto.getCondition())
                .ifPresent(s -> {
                    queryWrapper.and(wrapper -> wrapper
                            .like(Announcement::getContent, querySearchDto.getCondition())
                            .like(Announcement::getPublisher, querySearchDto.getCondition()));
                });
        return new Response(Response.SUCCEED_CODE, "查询公告内容", announcementService.page(page, queryWrapper));
    }

    //新增公告内容
    @Permissions("/announcement/insert")
    @LogInfo("Admin新增公告内容")
    @PostMapping("/insert")
    public Response insert(@Validated @RequestBody AnnouncementDto querySearchVo) {
        Announcement announcement = new Announcement();
        BeanUtils.copyProperties(querySearchVo, announcement);
        OperationLogsDto logsDto = new OperationLogsDto(
                -1, IpUtil.getIpAddress(getHttpInfo()), "Admin新增公告内容", getLogSign(), "标题：".concat(querySearchVo.getTitle()));
        boolean result = false;
        try {
            result = announcementService.save(announcement);
            logsDto.setOutcome(result ? 1 : 0);
            publisherAware.publisher(new LoggingApplicationEvent(logsDto));
        } catch (Exception e) {
            publisherAware.publisher(new LoggingApplicationEvent(logsDto));
            throw e;
        }
        return new Response(Response.SUCCEED_CODE, "新增公告内容", result);
    }

    //删除公告内容
    @Permissions("/announcement/delete")
    @LogInfo("Admin删除公告内容")
    @PostMapping("/delete")
    public Response delete(@RequestBody AnnouncementDto announcementVo) {
        OperationLogsDto logsDto = new OperationLogsDto(
                -1, IpUtil.getIpAddress(getHttpInfo()), "删除公告内容", getLogSign(), "标题：".concat(announcementVo.getTitle()));
        try {
            boolean result = announcementService.removeById(announcementVo.getId());
            if (result) {
                logsDto.setOutcome(1);
            } else {
                throw new SystemException(Response.ERROR_CODE, "未知错误");
            }
            publisherAware.publisher(new LoggingApplicationEvent(logsDto));
        } catch (Exception e) {
            publisherAware.publisher(new LoggingApplicationEvent(logsDto));
            throw e;
        }
        return new Response(Response.SUCCEED_CODE, "删除成功", null);
    }
}